{"cells":[{"metadata":{},"cell_type":"markdown","source":"### DM 5 - Terminale NSI - A rendre le 16 décembre (Correction)\n\nSujet : Centre Etrangers - Sujet 2 24-NSIJ2G11 juin 2024 - Ex 2 [6 points] : POO récursivité arbres binaires et les systèmes d’exploitation\n\n#### Partie A\n\n1.La commande Linux pour afficher le contenu du dossier documents est : `ls documents`.\n\n2.La commande : `mv ../../multimedia /home/documents` déplace le répertoire multimedia le dossier documents.\n \n L’arborescence devient :\n home\n ├── documents\n │ ├── cours\n │ ├── administratif\n │ ├── personnel\n │ └── multimedia\n │ ├── images\n │ └── videos\n │ └── films\n3."},{"metadata":{"trusted":false},"cell_type":"code","source":"class Arbre:\n def __init__(self, nom, gauche=None, droit=None):\n self.nom = nom\n self.gauche = gauche\n self.droit = droit\n\n def est_vide(self):\n return self.gauche is None and self.droit is None\n\n def parcours(self): # question 8\n print(self.nom)\n if self.gauche is not None:\n self.gauche.parcours()\n if self.droit is not None:\n self.droit.parcours()\n \n def parcours_suffixe(self): # question 10\n for f in self.fils: # Parcourt récursivement les sous-dossiers\n f.parcours_suffixe()\n print(self.nom) ","execution_count":1,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Le code donné avec la classe Arbre utilise uniquement deux attributs, gauche et droit, pour représenter les sous-dossiers. \n\nCela limite l’arborescence à deux fils maximum par nœud.\n\nCependant, dans une structure de fichiers comme celle de la figure 1. Chaque dossier peut avoir un nombre arbitraire de sous-dossiers (par exemple, documents a trois sous-dossiers : cours, administratif, personnel). \n\nLe code ne peut pas gérer cette situation avec seulement deux attributs (gauche, droit)."},{"metadata":{},"cell_type":"markdown","source":"4. Dans ce type de parcours :\n - On visite la racine en premier.\n - Ensuite, on parcourt récursivement le sous-arbre gauche.\n - Enfin, on parcourt récursivement le sous-arbre droit.\n \n Le parcours effectué par le code donné est donc un parcours `préfixe` (ou `préordre`).\n
\n \n5. Le parcours en largeur consiste à explorer les nœuds niveau par niveau, de gauche à droite. En utilisant l’arborescence de la figure 1 :\n\n Niveau 0 : home\n Niveau 1 : documents, multimedia\n Niveau 2 : cours, administratif, personnel, images, videos\n Niveau 3 : films\n\nRésultat du parcours en largeur : `home, documents, multimedia, cours, administratif, personnel, images, videos, films`.\n"},{"metadata":{},"cell_type":"markdown","source":"#### Partie B"},{"metadata":{},"cell_type":"markdown","source":"6. Un dossier est considéré vide si sa liste fils est vide."},{"metadata":{"trusted":false},"cell_type":"code","source":"class Dossier:\n def __init__(self, nom, liste):\n self.nom = nom\n self.fils = liste # Liste d'objets de type Dossier\n\n def est_vide(self):\n return len(self.fils) == 0\n \n def parcours(self): # c'est la réponse question 8, parcours en préfixe\n print(self.nom) # Affiche le nom du dossier courant\n for f in self.fils: # Parcourt récursivement les sous-dossiers\n f.parcours()\n \n def parcours_suffixe(self): # c'est la réponse question 10, parcours en suffixe\n for f in self.fils: # Parcourt récursivement les sous-dossiers\n f.parcours_suffixe()\n print(self.nom) # Affiche le nom du dossier courant\n \n def mkdir(self, nom_dossier): # c'est la réponse question 12, création d'un sous-dossier vide\n self.fils.append(Dossier(nom_dossier, []))\n \n def contient(self, nom_dossier): # c'est la réponse question 13, recherche d'un nom de dossier\n if self.nom == nom_dossier:\n return True\n\n for f in self.fils:\n if f.contient(nom_dossier): # Appel récursif\n return True\n\n return False","execution_count":26,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"7. L'instanciation de la variable var_multimedia représente le dossier multimedia de la figure 1 (avec ses sous-dossiers images et videos, et films en sous-dossier de videos), voici le code correspondant :"},{"metadata":{"trusted":false},"cell_type":"code","source":"var_films = Dossier(\"films\", [])\nvar_videos = Dossier(\"videos\", [var_films])\nvar_images = Dossier(\"images\", [])\nvar_multimedia = Dossier(\"multimedia\", [var_images, var_videos])","execution_count":27,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Explication :\n L’arborescence de la figure 1 est :\n \n home\n ├── documents\n │ ├── cours\n │ ├── administratif\n │ ├── personnel\n └── multimedia\n ├── images\n └── videos\n └── films\n\n Le dossier films est vide, donc sa liste fils est une liste vide [].\n Le dossier videos contient films comme sous-dossier.\n Le dossier multimedia contient images et videos comme sous-dossiers.\n \n8. \n\n def parcours(self):\n print(self.nom) # Affiche le nom du dossier courant\n for f in self.fils: # Parcourt récursivement les sous-dossiers\n f.parcours()"},{"metadata":{"trusted":false},"cell_type":"code","source":"# Appel de la méthode parcours en préfixe\nvar_multimedia.parcours()","execution_count":16,"outputs":[{"output_type":"stream","text":"multimedia\nimages\nvideos\nfilms\n","name":"stdout"}]},{"metadata":{},"cell_type":"markdown","source":"9. La méthode parcours termine toujours sur une arborescence de fichiers car lorsque la liste fils est vide (cas d’un dossier sans sous-dossier), la boucle for ne s’exécute pas, ce qui stoppe la récursion pour ce chemin.
\n\n10. \n\n def parcours_suffixe(self):\n for f in self.fils: # Parcourt récursivement les sous-dossiers\n f.parcours_suffixe()\n print(self.nom) # Affiche le nom du dossier courant"},{"metadata":{"trusted":false},"cell_type":"code","source":"# Appel de la méthode parcours en suffixe\nvar_multimedia.parcours_suffixe()","execution_count":17,"outputs":[{"output_type":"stream","text":"images\nfilms\nvideos\nmultimedia\n","name":"stdout"}]},{"metadata":{},"cell_type":"markdown","source":"11. La Commande UNIX ls affiche uniquement le contenu d’un dossier.\n Contrairement à la méthode parcours, qui descend récursivement dans les sous-dossiers et les affichent.\n \n12.\n\n def mkdir(self, nom_dossier):\n self.fils.append(Dossier(nom_dossier, []))"},{"metadata":{"trusted":false},"cell_type":"code","source":"# Exmple d'utilisation :\n\nvar_videos.mkdir(\"documentaires\")\n\n# Affichage des sous-dossiers de \"videos\"\nfor sous_dossier in var_videos.fils:\n print(sous_dossier.nom)","execution_count":18,"outputs":[{"output_type":"stream","text":"films\ndocumentaires\n","name":"stdout"}]},{"metadata":{},"cell_type":"markdown","source":"13.\n def contient(self, nom_dossier):\n if self.nom == nom_dossier:\n return True\n\n for f in self.fils:\n if f.contient(nom_dossier): # Appel récursif\n return True\n\n return False"},{"metadata":{"trusted":false},"cell_type":"code","source":"# # Exmple d'utilisation : Recherche d'un dossier\nprint(var_videos.contient(\"films\")) # Résultat : True\nprint(var_videos.contient(\"documentaires\")) # Résultat : True\nprint(var_videos.contient(\"series\")) # Résultat : False","execution_count":19,"outputs":[{"output_type":"stream","text":"True\nTrue\nFalse\n","name":"stdout"}]},{"metadata":{},"cell_type":"markdown","source":"14."},{"metadata":{"trusted":false},"cell_type":"code","source":"def trouver_parent(racine, nom_dossier):\n # Parcourt les fils du dossier courant\n for f in racine.fils:\n if f.nom == nom_dossier: # Si un des fils correspond au dossier recherché\n return racine # Retourne le dossier courant comme parent\n \n # Recherche récursive dans les sous-dossiers\n for f in racine.fils:\n parent = trouver_parent(f, nom_dossier)\n if parent: # Si un parent est trouvé dans un sous-arbre\n return parent\n \n # Si le dossier n'est trouvé dans aucun sous-dossier\n return None\n\n# Utilisation de trouver_parent\nparent_films = trouver_parent(var_multimedia, \"films\")\nif parent_films:\n print(f\"Le parent de 'films' est : {parent_films.nom}\")\nelse:\n print(\"Le dossier 'films' n'a pas de parent.\")","execution_count":31,"outputs":[{"output_type":"stream","text":"Le parent de 'films' est : videos\n","name":"stdout"}]},{"metadata":{},"cell_type":"markdown","source":"15."},{"metadata":{"trusted":false},"cell_type":"code","source":"class Dossier:\n def __init__(self, nom, fils, parent=None):\n self.nom = nom # Nom du dossier\n self.fils = fils # Liste des sous-dossiers\n self.parent = parent # Référence au dossier parent (par défaut None)\n\n # Met à jour l'attribut parent pour chaque sous-dossier\n for f in self.fils:\n f.parent = self\n \nvar_films = Dossier(\"films\", [])\nvar_videos = Dossier(\"videos\", [var_films])\nvar_images = Dossier(\"images\", [])\nvar_multimedia = Dossier(\"multimedia\", [var_images, var_videos])\n\n# Exemple : Trouver le parent d'un dossier\nif var_films.parent:\n print(f\"Le parent de 'films' est : {var_films.parent.nom}\")\nelse:\n print(\"Le dossier 'films' n'a pas de parent.\")","execution_count":36,"outputs":[{"output_type":"stream","text":"Le parent de 'films' est : videos\n","name":"stdout"}]}],"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"}},"nbformat":4,"nbformat_minor":2}